package cn.scw.project.facility.service.impl;

import cn.scw.common.PoiDoc;
import cn.scw.common.constant.Constants;
import cn.scw.common.constant.DictTypeConsts;
import cn.scw.common.constant.FacConsts;
import cn.scw.common.constant.GComConsts;
import cn.scw.common.exception.CustomException;
import cn.scw.common.separate.SeparateMethod;
import cn.scw.common.separate.model.MiniProgramModel;
import cn.scw.common.separate.response.MiniProgramResponse;
import cn.scw.common.utils.*;
import cn.scw.common.utils.bean.ToolUtils;
import cn.scw.common.utils.file.FileUploadUtils;
import cn.scw.common.utils.file.FileUtils;
import cn.scw.common.utils.http.HttpPrintUtils;
import cn.scw.common.utils.pay.ConfigUtil;
import cn.scw.common.utils.pay.PayUtils;
import cn.scw.common.utils.poi.WordUtil;
import cn.scw.common.utils.security.Md5Utils;
import cn.scw.common.utils.sql.SqlUtil;
import cn.scw.framework.aspectj.lang.annotation.DataScope;
import cn.scw.framework.web.domain.AjaxResult;
import cn.scw.framework.web.page.PageDomain;
import cn.scw.framework.web.page.TableSupport;
import cn.scw.project.facility.domain.FacPrintOrder;
import cn.scw.project.facility.domain.netework.bean.FacPrintOrderAddReq;
import cn.scw.project.facility.domain.netework.bean.FacPrintOrderListReq;
import cn.scw.project.facility.domain.vo.FacPrintOrderVo;
import cn.scw.project.facility.domain.vo.FacPrintPriceVo;
import cn.scw.project.facility.mapper.FacPrintOrderMapper;
import cn.scw.project.facility.service.IFacFacilityService;
import cn.scw.project.facility.service.IFacPrintOrderService;
import cn.scw.project.facility.service.IFacPrintPriceFacilityService;
import cn.scw.project.facility.service.IFacPrintTypeService;
import cn.scw.project.goods.domain.vo.GCouponUserVo;
import cn.scw.project.goods.service.IGCouponUserService;
import cn.scw.project.separate.domain.SeparateVo;
import cn.scw.project.separate.service.SaRecordService;
import cn.scw.project.system.domain.SysDealer;
import cn.scw.project.system.domain.SysUser;
import cn.scw.project.system.service.ISysDealerService;
import cn.scw.project.system.service.ISysDictDataService;
import cn.scw.project.system.service.ISysUserBrokerageService;
import cn.scw.project.system.service.ISysUserService;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * 打印订单Service业务层处理
 *
 * @author api
 * @date 2020-05-20
 */
@Service
public class FacPrintOrderServiceImpl implements IFacPrintOrderService {
    @Resource
    private FacPrintOrderMapper facPrintOrderMapper;
    @Autowired
    private IFacFacilityService iFacFacilityService;
    @Autowired
    private IGCouponUserService igCouponUserService;
    @Autowired
    private ISysDictDataService iSysDictDataService;
    @Autowired
    private IFacPrintTypeService iFacPrintTypeService;
    @Autowired
    private IFacPrintPriceFacilityService iFacPrintPriceFacilityService;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private ISysDealerService iSysDealerService;

    @Autowired
    private IFacPrintOrderService iFacPrintOrderService;

    @Autowired
    private ISysUserBrokerageService iSysUserBrokerageService;

    @Resource
    private SaRecordService saRecordService;

    @Resource
    private SeparateMethod separateMethod;

    @Value("${separate.notify}")
    private String separateNotify;

    /**
     * 查询打印订单
     *
     * @param id 打印订单ID
     * @return 打印订单
     */
    @Override
    public FacPrintOrder selectFacPrintOrderById(Long id) {
        return facPrintOrderMapper.selectFacPrintOrderById(id);
    }

    @Override
    public FacPrintOrderVo selectFacPrintOrderVoById(Long id) {
        return facPrintOrderMapper.selectFacPrintOrderVoById(id);
    }


    /**
     * 查询打印订单列表
     *
     * @param req 打印订单
     * @return 打印订单
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<FacPrintOrderVo> selectFacPrintOrderList(FacPrintOrderListReq req) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        SysDealer dealer = iSysDealerService.selectSysDealerByUserId(user.getUserId());
        if (dealer != null) {
            req.initData(dealer.getId());
        } else {
            req.initData();
        }
        startPage();
        List<FacPrintOrderVo> list =  facPrintOrderMapper.selectFacPrintOrderList(req);
        for(FacPrintOrderVo vo : list){
            List<SeparateVo> separateVos = saRecordService.querySeparateSuccRecord(vo.getId());
            if(!CollectionUtils.isEmpty(separateVos)){
                vo.setSeparate(true);
            }
        }
        return list;
    }

    private void startPage() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    @Override
    public List<FacPrintOrderVo> selectFacPrintOrderListByUser() {
        return facPrintOrderMapper.selectFacPrintOrderListByUser(SecurityUtils.getLoginUser().getUser().getUserId());
    }

    /**
     * 新增打印订单
     *
     * @param req 打印订单
     * @return 结果
     */
    @Override
    public AjaxResult insertFacPrintOrder(FacPrintOrderAddReq req) throws JDOMException, IOException {
        System.out.println("into insertFacPrintOrder");
        System.out.println("into insertFacPrintOrder req couponId=" + req.getCouponId());
        System.out.println("into insertFacPrintOrder req count=" + req.getCount());
        SysUser user = SecurityUtils.getLoginUser().getUser();
        user = iSysUserService.selectUserById(user.getUserId());
        if (StringUtils.isBlank(req.getFacilityCode()))
            throw new CustomException("请选择设备");
        if (!iFacFacilityService.existsByCode(req.getFacilityCode()))
            throw new CustomException("设备不存在");
        GCouponUserVo gCouponUser = null;
        if (req.getCouponId() != null) {
            gCouponUser = igCouponUserService.selectGCouponUserVoById(req.getCouponId());
            if (gCouponUser == null)
                throw new CustomException("优惠券不存在");
            igCouponUserService.verify(gCouponUser, GComConsts.COUPON_USE_SCOPE_PRINT);
            System.out.println("insertFacPrintOrder 检查到使用优惠券");

        }
        if (StringUtils.isBlank(req.getType()))
            throw new CustomException("请选择打印类型");
        if (!iSysDictDataService.existsDictLabel(DictTypeConsts.FAC_PRINT_TYPE, req.getPrintType()))
            throw new CustomException("请选择正确的打印类型");
        if (StringUtils.isBlank(req.getContent()))
            throw new CustomException("请上传打印内容");
        if (StringUtils.isBlank(req.getTypeCode()))
            throw new CustomException("请选择打印规格");
        if (!iFacPrintTypeService.existsByCode(req.getTypeCode()))
            throw new CustomException("请选择正确的打印规格");
        if (req.getCount() == null || req.getCount() < 1)
            throw new CustomException("请选择正确的打印份数");
        if (req.getCount() >= 100)
            throw new CustomException("一次打印份数最大为99");
        if (StringUtils.isBlank(req.getPrintType()))
            throw new CustomException("请选择打印方式");
        if (!iSysDictDataService.existsDictLabel(DictTypeConsts.FAC_ORDER_PRINT_TYPE, req.getPrintType()))
            throw new CustomException("请选择正确的打印方式");
        if (StringUtils.isBlank(req.getTitle()))
            throw new CustomException("请选择打印标题");
        if (!iSysDictDataService.existsDictLabel(DictTypeConsts.SYS_PAY_TYPE, req.getPayType()))
            throw new CustomException("请选择支付方式");
        if (req.getType().equals(FacConsts.PRINT_TYPE_DOCUMENT)) {
            String fileSuffix = req.getContent().substring(req.getContent().lastIndexOf(".")).toLowerCase();
            if (!fileSuffix.equals(".doc") && !fileSuffix.equals(".docx") && !fileSuffix.equals(".pdf") && !fileSuffix.equals(".wps")
                    && !fileSuffix.equals(".wpt") && !fileSuffix.equals(".dot") && !fileSuffix.equals(".rtf") && !fileSuffix.equals(".txt")
                    && !fileSuffix.equals(".dotx") && !fileSuffix.equals(".docm") && !fileSuffix.equals(".dotm") && !fileSuffix.equals(".xml")
                    && !fileSuffix.equals(".mht") && !fileSuffix.equals(".mhtml") && !fileSuffix.equals(".html") && !fileSuffix.equals(".htm")
                    && !fileSuffix.equals(".xls") && !fileSuffix.equals(".xlsx") && !fileSuffix.equals(".ppt") && !fileSuffix.equals(".pptx"))
                throw new CustomException("不支持的文件格式");
            if (req.getStartPage() == null || req.getEndPage() == null || req.getStartPage() < 1 || req.getStartPage() > req.getEndPage())
                throw new CustomException("请选择正确的打印范围");
            int pageCount = req.getEndPage() - req.getStartPage() + 1;
            if (pageCount > 99 || pageCount * req.getCount() > 99)
                throw new CustomException("打印总数量过多");
        }
        FacPrintOrder order = new FacPrintOrder();
        ToolUtils.copyPropertiesIgnoreNull(req, order);
        order.setColours(req.getIsColours());
        order.setCount(req.getCount());

        int count = order.getCount();
        // 计算文档打印实际打印张数
        if (req.getType().equals(FacConsts.PRINT_TYPE_DOCUMENT)) {
            count = PoiDoc.getCount(order.getContent()) * req.getCount();
        } else if (req.getType().equals(FacConsts.PRINT_TYPE_PICTURE) && req.getContent().contains(",")) {
            count = req.getContent().split(",").length * req.getCount();
        }
        // 未使用是否双面
        System.out.println("insertFacPrintOrder 设备标识=" + order.getFacilityCode() + "，订单类型=" + order.getTypeCode());

        FacPrintPriceVo facPrintPrice = iFacPrintPriceFacilityService.selectByFacilityCodeAndTypeAndIsColoursAndIsDoubleFacedAndPaperNumber(order.getFacilityCode(), order.getTypeCode(), req.getIsColours(), false, count);

        if (facPrintPrice == null) throw new CustomException("未找到对应的打印价格");
        double money =  BigDecimal.valueOf(count).multiply(BigDecimal.valueOf(facPrintPrice.getPrice())).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
        order.setPrice(facPrintPrice.getPrice());// 单价
        order.setMoney(money);// 订单总价
        System.out.println("insertFacPrintOrder 订单单价=" + order.getPrice() + "，订单总价=" + order.getMoney());
        if (gCouponUser != null) {
            double realPayMoney = BigDecimal.valueOf(money).subtract(BigDecimal.valueOf(gCouponUser.getGCoupon().getMoney())).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
            System.out.println("insertFacPrintOrder realPayMoney=" + realPayMoney);
            if (realPayMoney < 0)
                realPayMoney = 0;
            order.setPayMoney(realPayMoney);
        } else
            order.setPayMoney(money);

        System.out.println("insertFacPrintOrder 订单实付=" + order.getPayMoney());

        order.setUserId(user.getUserId());
        order.setNumber(UUIDUtils.getOrderNumberByUUId());

        // 调用支付方法 order.getPayType().equals(FacConsts.PAY_TYPE_WX) &&
        if (order.getPayMoney() > 0) {
            facPrintOrderMapper.insertFacPrintOrder(order);
            System.out.println("out insertFacPrintOrder wx");
            //插入分账记录
            List<Map<String, String>> fenzhangList = saRecordService.reckon(order.getId(), order.getFacilityCode(), new BigDecimal(order.getPayMoney()));

            boolean isNeedShare = CollectionUtils.isEmpty(fenzhangList)?false:true;
            return PayUtils.pay(order.getTitle(), order.getNumber(), order.getPayMoney(), user.getOpenId(), ConfigUtil.NOTIFY_URL_PRINT,isNeedShare);
//            List<Map<String, String>> fenzhangList = saRecordService.reckon(order.getId(), order.getFacilityCode(), new BigDecimal(order.getPayMoney()));
//            MiniProgramModel miniProgramModel = new MiniProgramModel();
//            miniProgramModel.setRequestNo(order.getNumber());
//            miniProgramModel.setOrderDate(DateUtils.parseDateToStr("yyyyMMdd", new Date()));
//            miniProgramModel.setOrderNo(order.getNumber());
//            miniProgramModel.setNotifyUrl(separateNotify);
//            miniProgramModel.setAmount(String.valueOf(order.getPayMoney()));
//            miniProgramModel.setPrdNm(order.getTitle());
//            miniProgramModel.setSubOpenId(user.getOpenId());
//            miniProgramModel.setSubAppId(ConfigUtil.APP_ID);
//            if (fenzhangList != null && fenzhangList.size() > 0) miniProgramModel.setFenZhangJsonStr(JSONArray.toJSONString(fenzhangList));
//            MiniProgramResponse response = separateMethod.payMethod(miniProgramModel);
//            if (!response.getSuccess()) return AjaxResult.error(StringUtils.isNotBlank(response.getRetMsg()) ? response.getRetMsg() : "下单失败，请稍后再试");
//            SortedMap<Object, Object> finalpackage = new TreeMap<>();
//            finalpackage.put("id", order.getId());
//            finalpackage.put("appId", response.getAppId());
//            finalpackage.put("timeStamp", response.getTimeStamp());
//            finalpackage.put("nonceStr", response.getNonceStr());
//            finalpackage.put("package", response.getPackAge());
//            finalpackage.put("signType", response.getSignType());
//            finalpackage.put("paySign", response.getPaySign());
//            return AjaxResult.success(finalpackage);
        }
//        if (order.getPayMoney() > 0) {
//            double userMoney = user.getMoney();
//            System.out.println("insertFacPrintOrder userMoney=" + userMoney);
//
//            if (userMoney < order.getPayMoney())
//                throw new CustomException("余额不足");
//            user.setMoney(userMoney - order.getPayMoney());
//            iSysUserService.updateUser(user);
//        } else {
//            // do nothing
//        }
        order.setPay(true);
        order.setPayDate(new Date());
        facPrintOrderMapper.insertFacPrintOrder(order);
        System.out.println("out insertFacPrintOrder other");

        // 更新优惠券使用状态
        if (gCouponUser != null) {
            System.out.println("更新优惠券使用状态");
            igCouponUserService.use(gCouponUser);
        }

        if (order.getCouponId() != null)
            igCouponUserService.use(igCouponUserService.selectGCouponUserVoById(order.getCouponId()));
        // 调用打印接口
        System.out.println("执行打印");
        boolean isPrint = HttpPrintUtils.print(order);
        order.setPrint(isPrint);
        iFacPrintOrderService.updateFacPrintOrder(order);
        // 计算佣金
        iSysUserBrokerageService.addSysUserBrokerageMoney(order.getFacilityCode(), order.getPayMoney());

        // todo 可能需要修改拆分
        return AjaxResult.success(order);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int pay(Long id, String payPassword) {
        SysUser user = iSysUserService.getCurrentUser();
        if (StringUtils.isBlank(user.getPayPassword())) throw new CustomException("请设置支付密码", 501);
        if (!user.getPayPassword().equals(Md5Utils.hash(payPassword))) throw new CustomException("支付密码不正确", 502);
        FacPrintOrder facPrintOrder = this.selectFacPrintOrderById(id);
        if (facPrintOrder == null) throw new CustomException("订单不存在");
        if (facPrintOrder.isPrint()) throw new CustomException("该订单已打印");
        if (!facPrintOrder.isPay()) {
            System.out.println(user.getMoney());
            System.out.println(facPrintOrder.getPayMoney());
            System.out.println(user.getMoney() < facPrintOrder.getPayMoney());
            if (user.getMoney() < facPrintOrder.getPayMoney()) throw new CustomException("余额不足");
            double money = user.getMoney() - facPrintOrder.getPayMoney();
            if (!iSysUserService.updateUserMoney(user.getUserId(), money)) throw new CustomException("支付失败");
            facPrintOrder.setPay(true);
            facPrintOrder.setPayDate(new Date());
            if (facPrintOrder.getCouponId() != null) igCouponUserService.use(igCouponUserService.selectGCouponUserVoById(facPrintOrder.getCouponId()));
        }
        // 调用打印
        boolean print = HttpPrintUtils.print(facPrintOrder);
        facPrintOrder.setPrint(print);
        return facPrintOrderMapper.updateFacPrintOrder(facPrintOrder);
    }

    @Override
    public FacPrintOrder selectFacPrintOrderByNumber(String number) {
        return facPrintOrderMapper.selectFacPrintOrderByNumber(number);
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public double countAll(SysDealer dealer) {
        return facPrintOrderMapper.countAll(dealer);
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public double countAllByDealer(SysDealer sysDealer) {
        return facPrintOrderMapper.countAllByDealer(sysDealer);
    }

    @Override
    public List<FacPrintOrderVo> selectFacPrintOrderPrintList(String code) {
        return facPrintOrderMapper.selectFacPrintOrderPrintList(code);
    }

    @Override
    public int print(Long id) {
        FacPrintOrder order = this.selectFacPrintOrderById(id);
        if (order == null)
            throw new CustomException("订单不存在");
        order.setPrint(true);
        return this.updateFacPrintOrder(order);
    }

    @Override
    public String imgSet(String path, int r, int g, int b) {
        // 获取图片地址ip前缀
        String prefixPath = path.substring(0, path.indexOf("upload/"));
        // 将ip地址路径替换成实际物理路径
        String newPath = FileUploadUtils.getDefaultBaseDir() + "/" + path.substring(path.indexOf("upload/"));

        // 处理图片后返回物理路径
        String imgPath = BaiduImgUtils.imgSet(newPath, r, g, b);
        // 截取实际物理路径后边文件路径，不要前边映射的实际路径
        String suffix = imgPath.substring(imgPath.indexOf("upload/"));
        // 删除处理前图片
        FileUtils.deleteFile(newPath);
        // ip前缀地址+文件地址路径
        return "https://xiaochengxu.printeasy.top/" + suffix;
        //return "http://127.0.0.1:6001/prod-api/profile/" + suffix;
    }

    @Override
    public String word(String content, int size) {
        String filePath = Constants.UPLOAD_FILE;
        String fileName = UUID.randomUUID().toString() + ".docx";
        String path = filePath + "/upload/" + fileName;
        WordUtil.creatDoc(path, content, size);
        return "/upload/" + fileName;
    }

    @Override
    public List<FacPrintOrder> selectUnSharingFacPrintOrder() {
        return facPrintOrderMapper.selectUnSharingFacPrintOrderList();
    }

    /**
     * 修改打印订单
     *
     * @param facPrintOrder 打印订单
     * @return 结果
     */
    @Override
    public int updateFacPrintOrder(FacPrintOrder facPrintOrder) {
        return facPrintOrderMapper.updateFacPrintOrder(facPrintOrder);
    }

    /**
     * 修改打印订单
     *
     * @param facPrintOrder 打印订单设备清零处理接口
     * @return 结果
     */
    @Override
    public int updateFacPrintOrderReset(FacPrintOrder facPrintOrder) {
        return facPrintOrderMapper.updateFacPrintOrderReset(facPrintOrder);
    }

    /**
     * 批量删除打印订单
     *
     * @param ids 需要删除的打印订单ID
     * @return 结果
     */
    @Override
    public int deleteFacPrintOrderByIds(Long[] ids) {
        return facPrintOrderMapper.deleteFacPrintOrderByIds(ids);
    }

    /**
     * 删除打印订单信息
     *
     * @param id 打印订单ID
     * @return 结果
     */
    @Override
    public int deleteFacPrintOrderById(Long id) {
        return facPrintOrderMapper.deleteFacPrintOrderById(id);
    }
}
